<template>
  <div>
    <!-- 面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right" style="margin-bottom:15px">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片视图区域 -->
    <el-card>
      <!-- 搜索与添加区域 -->
      <el-row :gutter="20">
        <!-- <el-col :span="8">
          <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getRoleList">
            <el-button slot="append" icon="el-icon-search" @click="getRoleList"></el-button>
          </el-input>
        </el-col> -->
        <el-col :span="4" >
          <el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
        </el-col>
      </el-row>

      <!-- 用户列表区域 -->
      <el-table :data="rolelist" border stripe  class="table" >

        <!-- 展开列 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
           <el-row :class="['bdbottom',i1 === 0 ? 'bdtop' : '', 'vcenter']" v-for="(item1, i1) in scope.row.children" :key="i1">
             <!-- 渲染一级权限 -->
             <el-col :span="5">
               <el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
               <i class="el-icon-caret-right"></i>
             </el-col>
             <!-- 渲染二级权限三级权限 -->
             <el-col :span="19">
               <!-- 通过 for 循环 嵌套渲染二级权限 -->
               <el-row :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']" v-for="(item2, i2) in item1.children" :key="i2">
                 <el-col :span="6">
                    <el-tag  closable @close="removeRightById(scope.row,item2.id)" type="success">{{item2.authName}}</el-tag>
               <i class="el-icon-caret-right"></i>
                 </el-col>
                 <el-col :span="18">
                    <el-tag  closable @close="removeRightById(scope.row,item3.id)" type="warning" v-for="(item3, i3) in item2.children" :key="i3">{{item3.authName}}</el-tag>
                 </el-col>
               </el-row>
             </el-col>
           </el-row>
          </template>
        </el-table-column>

        <!-- 索引列 -->
        <el-table-column type="index"></el-table-column>
        <el-table-column label="角色名称" prop="roleName"></el-table-column>
        <el-table-column label="角色描述" prop="roleDesc"></el-table-column>

        <el-table-column label="操作" width="180px">
          <template slot-scope="scope">
            <!-- 编辑按钮 -->
            <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.id)"></el-button>
            <!-- 删除按钮 -->
            <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeUserById(scope.row.id)"></el-button>
            <!-- 分配权限按钮 -->
            <el-tooltip effect="dark" content="分配角色" placement="top" :enterable="false">
              <el-button type="warning" icon="el-icon-setting" size="mini" @click="setRole(scope.row)"></el-button>
            </el-tooltip>
          </template>
        </el-table-column>

      </el-table>

       <!-- 分页区域 -->
      <!-- <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 5, 10]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
      </el-pagination> -->

    </el-card>

    <!-- 置顶 -->
    

    <!-- 添加用户的对话框 -->
     <el-dialog title="添加角色" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
     
      <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px">
        <el-form-item label="角色名称" >
          <el-input v-model="addForm.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" >
          <el-input v-model="addForm.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addUser">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 修改用户的对话框 -->
    <el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed">
      <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="70px">
        <el-form-item label="角色名称">
          <el-input v-model="editForm.roleName" ></el-input>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="editForm.roleDesc" ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editRolesInfo">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 分配角色权限的对话框 -->
     <el-dialog title="分配角色" :visible.sync="setRoleDialogVisible" width="50%" @close="setRightDialogClosed">
      <!-- 树形控件-->
      <el-tree show-checkbox node-key="id" default-expand-all ref="treeRef" :default-checked-keys="defKeys" :data="rightslist" :props="treeProps"></el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="setRoleDialogVisible = false">取 消</el-button>
        <el-button @click="allotRights" type="primary" >确 定</el-button>
      </span>
    </el-dialog> 

  </div>
</template>

<script>
export default {
  data() {
    // 验证邮箱的规则
    var checkEmail = (rule, value, cb) => {
      // 验证邮箱的正则表达式
      const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/

      if (regEmail.test(value)) {
        // 合法的邮箱
        return cb()
      }

      cb(new Error('请输入合法的邮箱'))
    }

    // 验证手机号的规则
    var checkMobile = (rule, value, cb) => {
      // 验证手机号的正则表达式
      const regMobile = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/

      if (regMobile.test(value)) {
        return cb()
      }

      cb(new Error('请输入合法的手机号'))
    }

    return {
      // 获取用户列表的参数对象
      queryInfo: {
        query: '',
        // 当前的页数
        pagenum: 1,
        // 当前每页显示多少条数据
        pagesize: 2
      },
      rolelist: [],
      total: 0,
      // 控制添加用户对话框的显示与隐藏
      addDialogVisible: false,
      // 添加用户的表单数据
      addForm: {
        roleName: '',
        roleDesc:''
      },
      // 添加表单的验证规则对象
      addFormRules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: '用户名的长度在3~10个字符之间',
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            min: 6,
            max: 15,
            message: '用户名的长度在6~15个字符之间',
            trigger: 'blur'
          }
        ],
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        mobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      },
      // 控制修改用户对话框的显示与隐藏
      editDialogVisible: false,
      // 查询到的用户信息对象
      editForm: {},
      // 修改表单的验证规则对象
      editFormRules: {
        email: [
          { required: true, message: '请输入用户邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        mobile: [
          { required: true, message: '请输入用户手机', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      },
      // 控制分配角色对话框的显示与隐藏
      setRoleDialogVisible: false,
      // 需要被分配角色的用户信息
      userInfo: {},
      // 所有角色的数据列表
      rightslist: [],
      // 树形控件的属性绑定对象
      treeProps:{
        label:'authName',
        children: 'children'
      },
      // 默认选中的节点Id值数组
      defKeys: [],
      // 当前即将分配权限的角色 id
      roleId:'',
    }

  },
  created() {
    this.getRoleList()
  },
  methods: {
    // 获取所有的角色列表
    async getRoleList() {
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status !== 200) {
        return this.$message.error('获取角色列表失败！')
      }
      // console.log(res);
      this.rolelist = res.data
      // console.log(res.data);
      this.total = res.data.total
      // console.log(this.total)
    },
    // 监听 pagesize 改变的事件
     handleSizeChange(newSize) {
       // console.log(newSize)
       this.queryInfo.pagesize = newSize
       this.getRoleList()
     },
    // // 监听 页码值 改变的事件
     handleCurrentChange(newPage) {
       // console.log(newPage)
       this.queryInfo.pagenum = newPage
       this.getRoleList()
     },
   
    // // 监听添加用户对话框的关闭事件
     addDialogClosed() {
       this.$refs.addFormRef.resetFields()
     },
     // 点击按钮，添加新用户
     addUser() {
       this.$refs.addFormRef.validate(async valid => {
         if (!valid) return
         // 可以发起添加用户的网络请求
         const { data: res } = await this.$http.post('roles', this.addForm)

         if (res.meta.status !== 201) {
           this.$message.error('添加用户失败！')
         }

         this.$message.success('添加用户成功！')
         // 隐藏添加用户的对话框
         this.addDialogVisible = false
         // 重新获取用户列表数据
         this.getRoleList()
       })
     },

    // // 展示编辑角色的对话框
     async showEditDialog(id) {
       // console.log(id)
       const { data: res } = await this.$http.get('roles/' + id)

       if (res.meta.status !== 200) {
         return this.$message.error('查询编辑角色失败！')
       }
       this.editForm = res.data
       this.editDialogVisible = true
     },

     // 监听修改角色对话框的关闭事件
     editDialogClosed() {
       this.$refs.editFormRef.resetFields()
     },

    // // 修改角色信息并提交
     editRolesInfo() {
       this.$refs.editFormRef.validate(async valid => {
         if (!valid) return
         // 发起修改用户信息的数据请求
         const { data: res } = await this.$http.put(
           'roles/' + this.editForm.id,
           {
             roleName: this.editForm.roleName,
             roleDesc: this.editForm.roleDesc
           }
         )

         if (res.meta.status !== 200) {
           return this.$message.error('更新角色信息失败！')
         }

      // 关闭对话框
         this.editDialogVisible = false
         // 刷新数据列表
         this.getRoleList()
         // 提示修改成功
         this.$message.success('更新角色信息成功！')
       })
     },

    // // 根据Id删除对应的角色信息
     async removeUserById(id) {
       // 弹框询问用户是否删除数据
       const confirmResult = await this.$confirm(
         '此操作将永久删除该用户, 是否继续?',
         '提示',
         {
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'warning'
         }
       ).catch(err => err)

       // 如果用户确认删除，则返回值为字符串 confirm
       // 如果用户取消了删除，则返回值为字符串 cancel
       // console.log(confirmResult)
       if (confirmResult !== 'confirm') {
         return this.$message.info('已取消删除')
       }

       const { data: res } = await this.$http.delete('roles/' + id)

       if (res.meta.status !== 200) {
         return this.$message.error('删除用户失败！')
       }

       this.$message.success('删除用户成功！')
       this.getRoleList()
     },

    // // 展示分配角色的对话框
     async setRole(role) {
        this.roleId = role

       // 在展示对话框之前，获取所有角色的列表
       const { data: res } = await this.$http.get('rights/tree')
       if (res.meta.status !== 200) {
         return this.$message.error('获取权限数据失败！')
       }

       this.rightslist = res.data

      // 递归获取三级节点的id
      
      this.getLeafKeys(role,this.defKeys)

       this.setRoleDialogVisible = true
     },

    // // 点击按钮，分配角色
    // async saveRoleInfo() {
    //   if (!this.selectedRoleId) {
    //     return this.$message.error('请选择要分配的角色！')
    //   }

    //   const { data: res } = await this.$http.put(
    //     `users/${this.userInfo.id}/role`,
    //     {
    //       rid: this.selectedRoleId
    //     }
    //   )

    //   if (res.meta.status !== 200) {
    //     return this.$message.error('更新角色失败！')
    //   }

    //   this.$message.success('更新角色成功！')
    //   this.getUserList()
    //   this.setRoleDialogVisible = false
    // },
    // // 监听分配角色对话框的关闭事件
    // setRoleDialogClosed() {
    //   this.selectedRoleId = ''
    //   this.userInfo = {}
    // }

    // 根据id删除对应的权限 
    async removeRightById(role,rightId){
      // 消息弹框
      const confirmResult = await this.$confirm(
         '此操作将永久删除该文件, 是否继续?',
         '提示',
         {
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'warning'
         }
       ).catch(err => err)
      if(confirmResult !== 'confirm'){
        return this.$message.info('取消了删除')
      }
        // console.log('确认了删除');
      const { data : res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)

      if(res.meta.status !== 200){
        return this.$message.error('删除权限失败')
      }
      // this.getRoleList();
      // 这样写是获取当前的最新的数据，删除时页面不会关闭 role 是传过来的
      role.children = res.data
    },

    // 通过递归的形式，获取角色下所有三级权限的 id 并保存到 defKeys: [] 中
    getLeafKeys(node,arr){
    // 如果当前的 node 节点不包含 children 属性 则是三级节点
    if(!node.children){
      return arr.push(node.id)
    }
    node.children.forEach(item => {
      this.getLeafKeys(item,arr)
    });
    },

    // 监听分配权限对话框
    setRightDialogClosed(){
      this.defKeys = []
    },

    // 点击为角色分配权限    接口不可用
    async allotRights(){
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        this.$refs.treeRef.getHalfCheckedKeys()
        ]
        // console.log(keys);
        const idStr = keys.join(',')
      const {data : res} = await  this.$http.post(`roles/${this.roleId}/rights`, {rids: idStr})
      if(res.meta.status !== 200){
        return this.$message.error('分配权限失败！')
      }
      this.$message.success('分配权限成功！')
      this.getRoleList()
      this.setRightDialogClosed = false
    }
    
  }
}
</script>

<style  scoped>
.el-tag{
  margin: 7px;
}
.bdtop {
  border-top: 1px solid #eee;
}
.bdbottom{
  border-bottom: 1px solid #eee;
}
.vcenter{
  display: flex;
  align-items: center;
}
.table{
margin-top:15px
}


</style>